﻿using System;
using System.Data;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Threading;
using System.Windows.Forms;
using RosarioFinanzas.ar.com.rosariofinanzas.www;
using System.Text;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.Data.OleDb;

namespace RosarioFinanzas
{
    public partial class frmEnvioMailNewletters : Form
    {
        private int posicion;
        private DataTable newsLetters;
        private Service1 service;
        static int contadorBar = 0;
        static int contador = 0;

        public frmEnvioMailNewletters()
        {
            InitializeComponent();
            service = new Service1();
        }

        #region EVENTOS

        private void frmEnvioMailNewletters_Load(object sender, EventArgs e)
        {
            try
            {
           //     CargarMails();
                CargarNewsLetterPendientes();
                lblProcessBar.Text = "Listo";
                lblCantMaxDest.Text = "7200";

                btnAceptar.Enabled = false;
            }

            catch (Exception ex)
            {
                RegistrarLog(ex.Message, ex.InnerException.Message, ex.Data.Values.ToString(), ex.StackTrace);
            }
        }

        private void btnAceptar_Click(object sender, EventArgs e)
        {
            try
            {
                if (chkMail.CheckedItems.Count == 0)
                {
                    MessageBox.Show("Debe seleccionar al menos un Mail a enviar.");
                    return;
                }

                lblProcessBar.Text = "Enviando...";
                EnvioMails envioMails = new EnvioMails();
                envioMails.destinatarios = new MailAddressCollection();

                contadorBar = progressBar.Maximum / (chkMail.CheckedItems.Count * newsLetters.Rows.Count);

                if (newsLetters.Rows.Count == 0)
                    return;

                foreach (DataRowView mailSeleccionado in chkMail.CheckedItems)  
                {

                    if (!IsEmailValid(mailSeleccionado[0].ToString().Trim()))
                        continue;

                        envioMails.destinatarios.Add(mailSeleccionado[0].ToString().Trim());

                        contador += 1;

                        if (DebeEnviarseEmail())
                        {
                            this.RealizarEnvio(envioMails, newsLetters.Rows[0]);
                            envioMails.destinatarios.Clear();
                        }
                    
                }

                if (envioMails.destinatarios.Count > 0)
                {
                    this.RealizarEnvio(envioMails, newsLetters.Rows[0]);
                    envioMails.destinatarios.Clear();
                }

                progressBar.Value = progressBar.Maximum;
                MessageBox.Show("Los mails han sido enviados correctamente.");
                lblProcessBar.Text = "Listo";
                progressBar.Value = 0;

                panel3.Controls.Clear();
                for (int item = 0; item < chkMail.Items.Count; item++)
                {
                    chkMail.SetItemChecked(item, false);
                }

                //CargarNewsLetterPendientes();

                ////update de newsLetters a ENVIADOS
                foreach (DataRow letter in newsLetters.Rows)
                {
                    service.UpdateEstadoNewsLetter((int)letter["id"]);
                }
            }

            catch (Exception ex)
            {
                RegistrarLog(ex.Message, ex.InnerException.Message, ex.Data.Values.ToString(), ex.StackTrace);
            }
        }

        private void btnCancelar_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void chkSeleccionarTodos_CheckedChanged(object sender, EventArgs e)
        {
            for (int item = 0; item < chkMail.Items.Count; item++)
            {
                chkMail.SetItemChecked(item, chkSeleccionarTodos.Checked);
            }
        }

        #endregion

        #region METODOS

        private void CargarMails()
        {
            var mailUsuarios = service.GetMailUsuarios();
            chkMail.DataSource = mailUsuarios;
            chkMail.DisplayMember = "mail";
            chkMail.ValueMember = "id";
            lblCantActualDest.Text = mailUsuarios.Rows.Count.ToString();
        }

        private void CargarNewsLetterPendientes()
        {
            posicion = 0;
            newsLetters = service.GetNewsLetterPendientes();
            foreach (DataRow mail in newsLetters.Rows)
            {
                ursNewletter newLetter = new ursNewletter();

                newLetter.SetBounds(1, posicion, 580, 92);
                newLetter.Parent = panel3;
                newLetter.Name = "ucnewLetter" + mail["Nombre"].ToString();
                newLetter.txtNombreValue = mail["Nombre"].ToString();
                newLetter.txtAsuntoValue = mail["Asunto"].ToString();
                newLetter.txtFechaValue = mail["Fecha"].ToString();
                newLetter.txtBoxHtmlValue = mail["HTML"].ToString();
                newLetter.CreateControl();
                posicion = posicion + 92;
            }
        }

        private void RegistrarLog(string mensaje, string innerException, string especificacion, string ruta)
        {
            string PATHLOG = @"C:\Log\EnvioNewsLetter";
            string ARCHIVOLOG = "ArchivoLog.txt";

            StreamWriter sw;
            string pathCompleto = PATHLOG + @"\" + ARCHIVOLOG;
            var dirInfo = new DirectoryInfo(PATHLOG);
            if (!dirInfo.Exists)
            {
                Directory.CreateDirectory(PATHLOG);
            }

            if (File.Exists(pathCompleto))
            {
                sw = File.AppendText(pathCompleto);
            }
            else
            {
                sw = File.CreateText(pathCompleto);
            }
            sw.WriteLine("-------------------------------------------------------------------------------");
            sw.WriteLine("Se ha producido un error. " + DateTime.Now.ToString());
            sw.WriteLine("-------------------------------------------------------------------------------");
            sw.WriteLine(mensaje);
            sw.WriteLine(innerException);
            sw.WriteLine(especificacion);
            sw.WriteLine(ruta);
            sw.Close();
        }

        public bool DebeEnviarseEmail()
        {
            
            const int cantMaximaDestinatarios = 100;

            for (int i = 1; i <= 70; i++)
            {

                if (cantMaximaDestinatarios * i == contador)
                    return true;
            }

            return false;

        }

        public bool IsEmailValid(string emailaddress)
        {
            try
            {
                MailAddress m = new MailAddress(emailaddress.Trim());

                return true;
            }
            catch (FormatException)
            {
                return false;
            }
        }

        public string GetEmail()
        {         

            // MUY IMPORTANTE !!!!!!

            // Para que GMAIL acepte usar estas cuestan desde nuestra aplicacion debemos ingresar a
            //    https://www.google.com/settings/security/lesssecureapps
            // Y hacer click en 'HABILITAR'
            // De lo contrario no podremos usarlas desde acá

            if(contador <= 900)
                return "rf.rosariofinanzas@gmail.com";

            if (contador <= 1800)
                return "rf2.rosariofinanzas@gmail.com";

            if (contador <= 2700)
                return "rf3.rosariofinanzas@gmail.com";

            if (contador <= 3600)
                return "rf4.rosariofinanzas@gmail.com";

            if (contador <= 4500)
                return "rf8.rosariofinanzas@gmail.com";

            if (contador <= 5400)
                return "rf10.rosariofinanzas@gmail.com";

            if (contador <= 6300)
                return "rf11.rosariofinanzas@gmail.com";

            //if (contador <= 7200)
            //    return "rf11.rosariofinanzas@gmail.com";


            return string.Empty;
        }

        private void RealizarEnvio(EnvioMails correo, DataRow letter)
        {
            if (contador <= 6300)
            {
                correo.mail = GetEmail();
                correo.letter = letter;
                Thread hiloEnvioMail = new Thread(correo.EnviarMailMultiplesDestinatarios);
                hiloEnvioMail.Start();
                hiloEnvioMail.Join();
                progressBar.Value += contadorBar;
            }
        }

                

        #endregion

        class EnvioMails
        {
            public DataRowView mailSeleccionado { get; set; }
            public DataRow letter { get; set; }
            public int contadorBar { get; set; }
            public string mail { get; set; }
            public MailAddressCollection destinatarios { get; set; }

            private string LinkExtension(string Link)
            {
                return Link.Substring(Link.LastIndexOf(".")+1 );
            }

            public void EnviarMail()
            {
                //Datos Servidor
                string sHost = "smtp.gmail.com";
                int iPort = 587;
                //int iPort = 465;
                //int iPort = 110;
                var cCredentials = new NetworkCredential(mail, "rosfin2011");
                //Datos Correo 
                string MailFrom = "info@rosariofinanzas.com.ar";
                string MailFromSuject = "Info Rosario Finanzas";
                string MailTo = mailSeleccionado.Row["mail"].ToString().Trim();
                //string MailTo = "pablo.garcia@neoris.com";
                string Suject = letter["Asunto"].ToString();
                string Body = letter["HTML"].ToString();


                /*AlternateView plainView =     AlternateView.CreateAlternateViewFromString(text,
                             Encoding.UTF8,
                             MediaTypeNames.Text.Plain);*/


                // Ahora creamos la vista para clientes que 
                // pueden mostrar contenido HTML...


                List<string> list = new List<string>();
                int c = 1;
                while(Body.IndexOf("<img alt=\"\" src=\"http")>0)
                {
                    string aux = Body.Substring(Body.IndexOf("<img alt=\"\" src=\"http")+17);
                    string aux2 = Body.Substring(Body.IndexOf("<img alt=\"\" src=\"http")+17, aux.IndexOf("\" />"));
                    if (aux2.IndexOf("style") > 0)
                        aux2 = aux2.Substring(0, aux2.IndexOf("style") - 2);
                    list.Add(aux2);
                    Body = Body.Replace(aux2,"cid:Imagen"+c.ToString());
                    c++;
                }
                
                AlternateView htmlView =
                    AlternateView.CreateAlternateViewFromString(Body,
                                            Encoding.UTF8,
                                            MediaTypeNames.Text.Html);

                // Creamos el recurso a incrustar. Observad
                // que el ID que le asignamos (arbitrario) está
                // referenciado desde el código HTML como origen
                // de la imagen (resaltado en amarillo)...
                c = 1;
                foreach(string link in list)
                {
                    LinkedResource img = null;
                    if (LinkExtension(link)== "Gif")
                        img = new LinkedResource(Link(link),MediaTypeNames.Image.Gif);
                    if (LinkExtension (link)== "jpg")
                        img = new LinkedResource(Link(link), MediaTypeNames.Image.Jpeg);
                    if (LinkExtension(link) != "jpg" && LinkExtension(link) != "Gif")
                        img = new LinkedResource(Link(link), "image/png");
                    img.ContentId = "Imagen" + c.ToString();
                    htmlView.LinkedResources.Add(img);
                    c++;
                }


                
                // Lo incrustamos en la vista HTML...

               
                

                // Lo incrustamos en la vista HTML...
                /*
                EmbeddedMailObject emo = new EmbeddedMailObject();
                emo.Path = @"~\Images\email\hdr_roar.gif";
                emo.Name = "hdr";

                EmbeddedMailObject emo2 = new EmbeddedMailObject();
                emo2.Path = @"~\Images\email\box_top.gif";
                emo2.Name = "box_top";

                message.EmbeddedObjects.Add(emo);
                message.EmbeddedObjects.Add(emo2);

                var msg = new MailDefinition();
                msg.EmbeddedObjects
                    */
                var correo = new MailMessage { From = new MailAddress(MailFrom, MailFromSuject) };
                correo.To.Add(MailTo);
                correo.Subject = Suject;
                
                //correo.Body = letter["Nombre"].ToString() + "\r\n" + "\r\n";
                //correo.Body = correo.Body + letter["HTML"].ToString() + "\r\n";
                //correo.Body = Body + "\r\n";
                correo.AlternateViews.Add(htmlView);
                //correo.IsBodyHtml = true;
                correo.Priority = MailPriority.Normal;
                var smtp = new SmtpClient
                    {
                        EnableSsl = true,
                        Host= sHost,
                        Port = iPort,
                        Credentials = cCredentials 
                    };
                //Host = "mail.rosariofinanzas.com.ar",
                
                smtp.Send(correo);
                contadorBar += contadorBar;
            }


            public void EnviarMailMultiplesDestinatarios()
            {
                //Datos Servidor
                string sHost = "smtp.gmail.com";
                int iPort = 587;
                //int iPort = 465;
                //int iPort = 110;
                var cCredentials = new NetworkCredential(mail, "rosfin2011");
                //Datos Correo 
                string MailFrom = "info@rosariofinanzas.com.ar";
                string MailFromSuject = "Info Rosario Finanzas";

                //string MailTo = "pablo.garcia@neoris.com";
                string Suject = letter["Asunto"].ToString();
                string Body = letter["HTML"].ToString();


                List<string> list = new List<string>();
                int c = 1;
                while (Body.IndexOf("<img alt=\"\" src=\"http") > 0)
                {
                    string aux = Body.Substring(Body.IndexOf("<img alt=\"\" src=\"http") + 17);
                    string aux2 = Body.Substring(Body.IndexOf("<img alt=\"\" src=\"http") + 17, aux.IndexOf("\" />"));
                    if (aux2.IndexOf("style") > 0)
                        aux2 = aux2.Substring(0, aux2.IndexOf("style") - 2);
                    list.Add(aux2);
                    Body = Body.Replace(aux2, "cid:Imagen" + c.ToString());
                    c++;
                }

                AlternateView htmlView =
                    AlternateView.CreateAlternateViewFromString(Body,
                                            Encoding.UTF8,
                                            MediaTypeNames.Text.Html);


                c = 1;
                foreach (string link in list)
                {
                    LinkedResource img = null;
                    if (LinkExtension(link) == "Gif")
                        img = new LinkedResource(Link(link), MediaTypeNames.Image.Gif);
                    if (LinkExtension(link) == "jpg")
                        img = new LinkedResource(Link(link), MediaTypeNames.Image.Jpeg);
                    if (LinkExtension(link) != "jpg" && LinkExtension(link) != "Gif")
                        img = new LinkedResource(Link(link), "image/png");
                    img.ContentId = "Imagen" + c.ToString();
                    htmlView.LinkedResources.Add(img);
                    c++;
                }


                var correo = new MailMessage { From = new MailAddress(MailFrom, MailFromSuject) };
         
                foreach (var item in destinatarios)
                {
                    correo.Bcc.Add(item);
                }

                correo.Subject = Suject;

                correo.AlternateViews.Add(htmlView);
                //correo.IsBodyHtml = true;
                correo.Priority = MailPriority.Normal;
                var smtp = new SmtpClient
                {
                    EnableSsl = true,
                    Host = sHost,
                    Port = iPort,
                    Credentials = cCredentials
                };
                //Host = "mail.rosariofinanzas.com.ar",

                smtp.Send(correo);
                contadorBar += contadorBar;
            }

            private Stream Link(string link)
            {
                //Create a stream for the file
                Stream stream = null;

                //This controls how many bytes to read at a time and send to the client
                int bytesToRead = 10000;

                // Buffer to read bytes in chunk size specified above
                byte[] buffer = new Byte[bytesToRead];

                // The number of bytes read
               
                    //Create a WebRequest to get the file
                
                    /*
                    HttpWebRequest fileReq = (HttpWebRequest)HttpWebRequest.Create(link);
                    fileReq.Timeout = 120000;

                    //Create a response for this request
                    HttpWebResponse fileResp = (HttpWebResponse)fileReq.GetResponse();

                    if (fileReq.ContentLength > 0)
                        fileResp.ContentLength = fileReq.ContentLength;

                    //Get the Stream returned from the response
                    fileReq.GetRequestStream*/
                    
                  /*  FileWebRequest fileReq = (FileWebRequest)FileWebRequest.Create(link);
                    fileReq.Timeout = 120000;

                    //Create a response for this request
                    FileWebResponse fileResp = (FileWebResponse)fileReq.GetResponse();

                    if (fileReq.ContentLength > 0)
                        fileResp.ContentLength = fileReq.ContentLength;

                    //Get the Stream returned from the response
                
                    stream = fileResp.GetResponseStream();

                */
                    WebClient wc = new WebClient();
                    byte[] b = wc.DownloadData(link);

                    Stream ms = new MemoryStream(b);
                    //ms.WriteTo(stream);

                   // using (MemoryStream ms = new MemoryStream(b)) 
                    

                    return ms;
                    /*
                    // prepare the response to the client. resp is the client Response
                    var resp = HttpContext.Current.Response;

                    //Indicate the type of data being sent
                    resp.ContentType = "application/octet-stream";

                    //Name the file 
                    resp.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
                    resp.AddHeader("Content-Length", fileResp.ContentLength.ToString());

                    int length;
                    do
                    {
                        // Verify that the client is connected.
                        if (resp.IsClientConnected)
                        {
                            // Read data into the buffer.
                            length = stream.Read(buffer, 0, bytesToRead);

                            // and write it out to the response's output stream
                            resp.OutputStream.Write(buffer, 0, length);

                            // Flush the data
                            resp.Flush();

                            //Clear the buffer
                            buffer = new Byte[bytesToRead];
                        }
                        else
                        {
                            // cancel the download if client has disconnected
                            length = -1;
                        }
                    } while (length > 0); //Repeat until no data is read*/
               
            }
        }

        private void btnCargaEmails_Click(object sender, EventArgs e)
        {

            openFileDialog1.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";

            DialogResult result = openFileDialog1.ShowDialog(); // Show the dialog.

            if (result == DialogResult.OK) // Test result.
            {              
			   
                if (System.IO.File.Exists(openFileDialog1.FileName))
                {
                    //Dimensionar los elementos necesarios para leer y cargar los datos
                    OleDbConnection oConn = new OleDbConnection();
                    OleDbCommand oCmd = new OleDbCommand();
                    OleDbDataAdapter oDa = new OleDbDataAdapter();
                    DataSet oDs = new DataSet();
                    //Atención: Esta es la cadena de conexión. La misma lee el archivo especificado en el path
                    oConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + openFileDialog1.FileName + "; Extended Properties= Excel 8.0;";
                    //Abrir la conexión, y leer [Hoja 1] del archivo Excel
                    oConn.Open();
                    oCmd.CommandText = "SELECT * FROM " + "[Worksheet$]";
                    oCmd.Connection = oConn;
                    oDa.SelectCommand = oCmd;
                    //Llenar el DataSet
                    oDa.Fill(oDs, "Migracion");

                    DataTable dtEmails = new DataTable("Emails");
                    DataColumn dtcol2 = new DataColumn("Email", typeof(String));
                    dtEmails.Columns.Add(dtcol2);

                    foreach (DataRow dr in oDs.Tables[0].Rows)
                    {

                        if (dr[0].ToString() == string.Empty)
                            continue;
                        
                        DataRow drEmail = dtEmails.NewRow();
                        drEmail[0] = dr[0];
                        dtEmails.Rows.Add(drEmail);

                    }

                    chkMail.DataSource = dtEmails;
                    chkMail.DisplayMember = "Email";
                    chkMail.ValueMember = "Email";
                    lblCantActualDest.Text = dtEmails.Rows.Count.ToString();
				  
				  
                    oConn.Close();

                    btnAceptar.Enabled = true;

                }
			   
			   
			   
			   
			   
			   
			   
			   
			   
            }




        }


    }
}
